# ~*~ coding: utf-8 ~*~
from flask import request, views, render_template, jsonify
from flask_login import current_user

from apps.common.utils import timestamp_obj_to_str, fill_date_to_timestamp
from apps.perms.mixin import PermissionRequiredMixin, LoginRequiredMixin, LoginRequiredAndCsrfExemptMixin
from apps.extensions import db
from apps.assets.models import Asset
from ..elfinder import connector
from ..elfinder import volumes
from ..service.utils import get_cached_volume, set_cache_volume
from ..service.models import RequestConnection
from ..service.sftp import InternalSFTPClient
from ..models import SFTPLog


__all__ = ['SftpConnectorView', 'SftpConnectorHostView', 'SftpHostConnectorAPI', 'SFTPLogAPI', 'SFTPLogView']


class SftpConnectorView(LoginRequiredMixin, PermissionRequiredMixin, views.MethodView):
    permission_required = 'terminal-sftp-connector'

    def get(self):
        return render_template('terminal/sftp_terminal.html', host='_')


class SftpConnectorHostView(LoginRequiredMixin, PermissionRequiredMixin, views.MethodView):
    permission_required = 'terminal-sftp-connector'

    def get(self, host):
        return render_template('terminal/sftp_terminal.html', host=host)


class SftpHostConnectorAPI(LoginRequiredAndCsrfExemptMixin, PermissionRequiredMixin, views.MethodView):
    permission_required = 'terminal-sftp-connector'

    def get(self, host):
        sid = request.args.get("sid") or request.values.get('sid')
        volume = get_cached_volume(sid) if sid else None
        if not volume:
            connection = RequestConnection(addr=(request.remote_addr, 0))
            connection.user = current_user

            sftp = InternalSFTPClient(connection)
            volume = volumes.SFTPVolume(sftp)
            set_cache_volume(sid, volume)

        if host != '_':
            asset = db.session.query(Asset).filter(Asset.hostname == host).first()

            if not asset:
                return jsonify({'error': 'Not found this host'})
            volume.root_name = asset.hostname
            volume.base_path = '/' + asset.hostname

        handler = connector.ElFinderConnector([volume])
        handler.run(request)

        # If download file, return a view response
        if handler.return_view:
            return handler.return_view
        if handler.headers['Content-type'] == 'application/json':
            return jsonify(handler.response)

    def post(self, host):
        return self.get(host=host)


class SFTPLogAPI(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'terminal-sftp-log'

    def get(self):
        create_time = request.args.get('create_time')
        start_time = end_time = None
        if create_time:
            start_time = fill_date_to_timestamp('start', create_time.split('~')[0])
            end_time = fill_date_to_timestamp('end', create_time.split('~')[1])

        filter_conditions = {
            'and': [
                ('create_time', 'gte', start_time),
                ('create_time', 'lte', end_time),
            ],
            'or': [
                ('name', 'like', request.args.get('search')),
            ],
        }

        # 排序
        sort = request.args.get('sort') or 'create_time'
        order = request.args.get('order') or 'desc'
        order_by_list = [(sort, order), ]

        # 分页
        offset = request.args.get('offset') or 0
        limit = request.args.get('limit') or 12

        logs, count = SFTPLog.get_queryset(filter_conditions=filter_conditions,
                                           order_by_list=order_by_list,
                                           offset=offset, limit=limit)
        results = list()
        for log in logs:
            results.append({
                'id': log.id,
                'user': log.user,
                'asset': log.asset,
                'system_user': log.system_user,
                'remote_addr': log.remote_addr,
                'operate': log.operate,
                'filename': log.filename,
                'is_success': 1 if log.is_success else 0,
                'create_time': timestamp_obj_to_str(log.create_time)
            })

        resp = {
            "data": {
                "rows": results,
                "total": count
            }
        }
        return jsonify(resp)


class SFTPLogView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'terminal-sftp-log'

    def get(self):
        return render_template('terminal/sftp_log.html')
